﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ERP.Common.Model;
using ERP.EFCore;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;

namespace ERP.Web.Core.Pocket
{
    public static class PocketHelper
    {
        /// <summary>
        /// 获取DataContext
        /// </summary>
        /// <param name="ctx"></param>
        /// <returns></returns>
        public static DataContext GetDbContext(this HttpContext ctx)
        {
            return ctx.RequestServices.GetRequiredService<DataContext>();
        }

        /// <summary>
        /// Service的Pocket拓展方法
        /// </summary>
        /// <typeparam name="TSource">注入类型</typeparam>
        /// <param name="services">services扩展</param>
        /// <param name="resultBuilder"></param>
        /// <returns></returns>
        public static IServiceCollection AddPocket<TSource>(this IServiceCollection services, Func<HttpContext, IList<SimpleItemModel>> resultBuilder)
        {

            var tPocket = typeof(ResultObtainer<HttpContext, IList<SimpleItemModel>>);
            if (!(services.SingleOrDefault(s => s.ServiceType == tPocket)?.ImplementationInstance is ResultObtainer<HttpContext, IList<SimpleItemModel>> ro))
            {
                ro = new ResultObtainer<HttpContext, IList<SimpleItemModel>>(typeof(TSource), resultBuilder);
                services.Add(new ServiceDescriptor(tPocket, ro));
            }
            ro.RegisterLane(typeof(TSource), resultBuilder);
            return services;
        }
        /// <summary>
        /// 获取Action自定义特性集合
        /// </summary>
        /// <typeparam name="TAttribute">Controller类型</typeparam>
        /// <param name="desc"></param>
        /// <returns></returns>
        public static IEnumerable<TAttribute> RetrieveCustomAttribute<TAttribute>(this ControllerActionDescriptor desc)
            where TAttribute : Attribute
        {
            return desc.MethodInfo.GetCustomAttributes<TAttribute>(true);
        }

        /// <summary>
        /// 获取Pocket的注入结果
        /// </summary>
        /// <typeparam name="TParameter"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="sp"></param>
        /// <param name="parameter"></param>
        /// <param name="lane"></param>
        /// <returns></returns>
        public static TResult ObtainPocketResult<TParameter, TResult>(this IServiceProvider sp, TParameter parameter, object lane)
            where TResult : class
        {
            return sp.GetService<ResultObtainer<TParameter, TResult>>().ObtainResult(parameter, lane);
        }
    }
}
